﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
namespace Wika
{

    public partial class Form1 : Form
    {

        private static int NUM_CLUSTERS = 0;//
        private static int TOTAL_DATA = 0;//
        private static List<Data> SAMPLES = new List<Data>();
        private static List<Data> dataset = new List<Data>();
        private static List<Centroid> centroids = new List<Centroid>();

        Cot Columns;
        Bang Table;
        public Form1()
        {
            InitializeComponent();
            Columns = new Cot(); // tao doi tuong tieu de
            Table = new Bang();// tao doi tuong bang
            ((Control)this.tabPage2).Enabled = false;
        }
        //tim trung tam cua du lieu
        private Centroid centroidOfData(List<Data> SAMPLES)
        {
            List<double> lst = new List<double>();

            int d=SAMPLES[0].getDimension();
            int r=SAMPLES.Count;
            double[] totalOfDimensons = new double[d];
            for (int i = 0; i < d; i++)
            {
                double sofoneD = 0.0; // sum of one Dimension
                
                for (int j = 0; j < r; j++)
                {
                    sofoneD += SAMPLES[j].getElementAt(i);
                }
                lst.Add(sofoneD/r);
            }
            Centroid c = new Centroid(lst);
            return c;
        } 
        // sap xep
        private void sapxep(List<double> distLst)
        {
            int n=distLst.Count;
            for(int i=0;i<=n-2;i++)
                for(int j=i+1;j<=n-1;j++)
                    if(distLst[i] > distLst[j])
                    {
                        double tmp = distLst[i];
                        distLst[i] = distLst[j];
                        distLst[j] = tmp;
                    }

        }
        //khoag cach cac diem den trung tam da duoc sap xep
        private List<double> distPointToCentroid(List<Data> SAMPLES, Centroid c)
        {
            List<double> lst = new List<double>();
            for (int i = 0; i < SAMPLES.Count; i++)
            {
                lst.Add(Math.Round(dist(SAMPLES[i], c), 2));
            }
            sapxep(lst);
            return lst;
        }
        private Centroid findPoint(List<Data> SAMPLES,Centroid c,double x)
        {
            
            for(int i=0;i<SAMPLES.Count;i++)
                if (Math.Round( dist(SAMPLES[i], c),2)== x)
                {
                    return SAMPLES[i].toCentroid();
                }
            return null;
        }
        #region User Define


        private List<double> toDoubleArray(String[] p1)
        {
            List<double> lst = new List<double>();
            for (int i = 0; i < p1.Length; i++)
            {

                double x = 0.0;/*Math.Round( Double.Parse(p1[i]),2);*/
                if (Double.TryParse(p1[i], out x) == true)
                {
                    x = Math.Round(x, 2);
                    lst.Add(x);
                }
               
            }
            return lst;
        }

        private void AddLine(ListView lst, int No, String Name)
        {
            lst.Items.Add(No.ToString()).SubItems.Add(Name);
        }
        //Dem gia tri bi thieu
        private int countMissing(Bang tb, int iCot)
        {
            int count = 0;
            for (int i = 0; i < tb.mau.Count; i++)
                if (tb.mau[i].giatri[iCot].CompareTo("?") == 0)
                    count++;
            return count;
        }

        private String RowtoString(Dong d) // chuyen 1 dong trong csdl thanh 1 chuoi de ghi xuong file
        {
            String output = "";
            for (int i = 0; i < d.giatri.Length; i++)
                if (i + 1 != d.giatri.Length)
                    output = output + d.giatri[i] + ",";
                else
                    output = output + d.giatri[i] + "\n";
            return output;

        }
        // kiem tra kieu du lieu 1 cot la numeric hay nominal
        private int getType(Bang tb, int iCot) //0 nominal, 1 numeric
        {
            int count = 0;
            int kq = 0;
            for (int i = 0; i < tb.mau.Count; i++)
                if (TryParse(tb.mau[i].giatri[iCot]) == true)
                    return 1;
            return 0;
        }

        private bool TryParse(String x)
        {
            int kq = 0;
            double re = 0;
            if (int.TryParse(x, out kq) == true)
                return true;
            if (double.TryParse(x, out re) == true)
                return true;
            return false;
        }

        private int[] Missing_getType(Bang tb, int iCot)
        {
            int[] arr = new int[2];
            arr[0] = 0; //dem so dong miss
            arr[1] = 0; //kiem tra 0 nominal, 1 numeric
            for (int i = 0; i < tb.mau.Count; i++)
            {
                if (tb.mau[i].giatri[iCot].CompareTo("?") == 0)
                    arr[0]++;
                if (TryParse(tb.mau[i].giatri[iCot]) == true)
                    arr[1] = 1;
            }
            return arr;
        }

        private double Mean(Bang tb, int iCot)
        {
            if (tb.mau.Count == 0)
                return 0;
            double s = 0;
            for (int i = 0; i < tb.mau.Count; i++)
                if (tb.mau[i].giatri[iCot].CompareTo("?") != 0)
                    s = s + double.Parse(tb.mau[i].giatri[iCot], System.Globalization.CultureInfo.CurrentCulture);
            return s / tb.mau.Count;
        }
        private double stdDev(Bang tb, int iCot)
        {
            if (tb.mau.Count == 0)
                return 0;
            double mean = Mean(tb, iCot);
            double xichma = 0;
            for (int i = 0; i < tb.mau.Count; i++)
                if (tb.mau[i].giatri[iCot].CompareTo("?") != 0)
                {
                    double x = double.Parse(tb.mau[i].giatri[iCot], System.Globalization.CultureInfo.CurrentCulture);
                    xichma = xichma + ((x - mean) * (x - mean));
                }
            double svar = xichma / (double)1 / (tb.mau.Count - 1);
            return Math.Round(Math.Sqrt(svar), 3);
        }
        private int frequency(Bang tb, int iCot, String x)
        {
            int count = 0;
            for (int i = 0; i < tb.mau.Count; i++)
                if (tb.mau[i].giatri[iCot].CompareTo(x) == 0)
                    count++;
            return count;
        }

        private String maxFrequency(Bang tb, int iCot) // tra ve gia tri co tan so nhieu nhat
        {
            if (tb.mau.Count == 0)
                return "";
            int ts = frequency(tb, iCot, tb.mau[0].giatri[iCot]);
            String value = tb.mau[0].giatri[iCot];
            for (int i = 0; i < tb.mau.Count; i++)
                if (frequency(tb, iCot, tb.mau[i].giatri[iCot]) > ts)
                {
                    ts = frequency(tb, iCot, tb.mau[i].giatri[iCot]);
                    value = tb.mau[i].giatri[iCot];
                }
            return value;
        }

        private void replaceMissingvalue(Bang tb, Cot col)
        {
            try
            {
                progressBar1.Value = 0;
                progressBar1.Minimum = 0;
                progressBar1.Maximum = col.thuoctinh.Length - 1;
                progressBar1.Step = 1;
                for (int i = 0; i < col.thuoctinh.Length; i++)
                {
                    if (getType(tb, i) == 0)
                    {
                        String mode = maxFrequency(tb, i);
                        for (int j = 0; j < tb.mau.Count; j++)
                            if (tb.mau[j].giatri[i].CompareTo("?") == 0)
                                tb.mau[j].giatri[i] = mode;
                    }
                    else
                    {
                        double mdn = Mean(tb, i);
                        for (int j = 0; j < tb.mau.Count; j++)
                            if (tb.mau[j].giatri[i].CompareTo("?") == 0)
                                tb.mau[j].giatri[i] = mdn.ToString();
                    }
                    progressBar1.PerformStep();
                }
            }
            catch (NullReferenceException)
            {
                MessageBox.Show("Chưa Chọn Tập Dữ Liệu");
            }

        }

        private void SaveFile(String filename)
        {
            progressBar2.Value = 0;
            progressBar2.Minimum = 0;
            progressBar2.Maximum = Table.mau.Count + 1;
            progressBar2.Step = 1;
            FileStream fs = new FileStream(filename, FileMode.Create);
            StreamWriter sw = new StreamWriter(fs);
            for (int i = 0; i < Columns.thuoctinh.Length; i++)
                if (i + 1 != Columns.thuoctinh.Length)
                {
                    sw.Write(Columns.thuoctinh[i] + ",");
                    progressBar2.PerformStep();
                }
                else
                {
                    sw.Write(Columns.thuoctinh[i] + "\n");
                    progressBar2.PerformStep();
                }
            for (int i = 0; i < Table.mau.Count; i++)
            {
                sw.Write(RowtoString(Table.mau[i]));
                progressBar2.PerformStep();
            }

            sw.Close();
        }
        private Double KhacChamHoiDauTien(Bang tb, int iCot)
        {

            Double db = new Double();
            for (int i = 0; i < tb.mau.Count; i++)
                if (tb.mau[i].giatri[iCot].CompareTo("?") != 0)
                    return double.Parse(tb.mau[i].giatri[iCot], System.Globalization.CultureInfo.CurrentCulture);
            return db;

        }
        private double[] Statics(Bang tb, int iCot)
        {

            if (tb.mau.Count == 0)
                return null;
            double[] s = new double[4];
            s[0] = KhacChamHoiDauTien(Table, iCot);//Minimum
            s[1] = KhacChamHoiDauTien(Table, iCot);//Maximum
            s[2] = 0;//Mean
            s[3] = 0;//stdDev
            for (int i = 0; i < tb.mau.Count; i++)
                if (tb.mau[i].giatri[iCot].CompareTo("?") != 0)
                {
                    double var = double.Parse(tb.mau[i].giatri[iCot], System.Globalization.CultureInfo.CurrentCulture);
                    if (var < s[0])
                        s[0] = var; //Minimum
                    if (var > s[1])
                        s[1] = var; //Maximum
                    s[2] = s[2] + var;// Mean
                }
            s[2] = s[2] / tb.mau.Count;
            return s;
        }

        private void min_max_Normalize(Bang tb, int iCot, double newmin, double newmax)
        {
            if (getType(tb, iCot) == 0)
                throw new InvalidDataException();
            progressBar3.Value = 0;
            progressBar3.Minimum = 0;
            progressBar3.Maximum = tb.mau.Count;
            double[] stsc = Statics(tb, iCot);
            for (int i = 0; i < tb.mau.Count; i++)
            {
                if (tb.mau[i].giatri[iCot].CompareTo("?") != 0)
                {
                    double v = double.Parse(tb.mau[i].giatri[iCot], System.Globalization.CultureInfo.CurrentCulture);
                    double tuso = v - stsc[0];
                    double mauso = stsc[1] - stsc[0];
                    double v_ = ((tuso / mauso) * (newmax - newmin)) + newmin;
                    tb.mau[i].giatri[iCot] = v_.ToString();
                    progressBar3.PerformStep();
                }
            }
        }
        private void z_score_Normalize(Bang tb, int iCot, double stdDev)
        {
            if (getType(tb, iCot) == 0)
                throw new InvalidDataException();
            progressBar4.Value = 0;
            progressBar4.Minimum = 0;
            progressBar4.Maximum = tb.mau.Count;
            double mean = Mean(tb, iCot);
            for (int i = 0; i < tb.mau.Count; i++)
            {
                if (tb.mau[i].giatri[iCot].CompareTo("?") != 0)
                {
                    double v = double.Parse(tb.mau[i].giatri[iCot], System.Globalization.CultureInfo.CurrentCulture);
                    double v_ = (v - mean) / stdDev;
                    tb.mau[i].giatri[iCot] = v_.ToString();
                    progressBar4.PerformStep();
                }
            }
        }
        private List<bin> binning(Bang tb, int iCot, int n) // tra ve danh sach cac khoang cua cot can chia gio
        {
            List<bin> bins = new List<bin>();
            double[] sts = Statics(tb, iCot);
            double dorong = Math.Round((sts[1] - sts[0]) / (double)n, 3);
            double min, max;
            min = sts[0];
            for (int i = 0; i < n; i++)
            {
                bin b = new bin();
                b.Min = min;
                min += dorong;
                b.Max = min;
                bins.Add(b);
            }
            return bins;
        }
        private List<bin> binning2(Bang tb, int iCot, int n) // tra ve danh sach cac khoang cua cot can chia gio
        {
            List<bin> bins = new List<bin>();
            double[] sts = Statics(tb, iCot);
            double dorong = Math.Round((sts[1] - sts[0]) / (double)n, 3);
            double min, max;
            min = sts[0];
            for (int i = 0; i < n; i++)
            {
                bin b = new bin();
                b.Min = min;
                min += dorong;
                b.Max = min;
                bins.Add(b);
            }
            return bins;
        }
        private void hoanviDong(Bang tb, int m, int n)
        {
            Dong temp = tb.mau[n];
            tb.mau[n] = tb.mau[m];
            tb.mau[m] = temp;
        }
        private void sapxepcot(Bang tb, int iCot)
        {
            for (int i = 0; i <= tb.mau.Count - 2; i++)
                for (int j = i + 1; j <= tb.mau.Count - 1; j++)
                    if (tb.mau[i].giatri[iCot].CompareTo("?") != 0 && tb.mau[j].giatri[iCot].CompareTo("?") != 0)
                    {
                        double a = double.Parse(tb.mau[i].giatri[iCot], System.Globalization.CultureInfo.CurrentCulture);
                        double b = double.Parse(tb.mau[j].giatri[iCot], System.Globalization.CultureInfo.CurrentCulture);
                        if (a > b)
                        {
                            hoanviDong(Table, i, j);
                        }
                    }
        }
        #endregion
        #region Event
        //DOC FILE DU LIEU
        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                progressBar1.Value = 0;
                progressBar2.Value = 0;
                openFileDialog1.ShowDialog();
                StreamReader sr = new StreamReader(openFileDialog1.FileName); // tao doi tuong de doc file
                if (Path.GetExtension(openFileDialog1.FileName).CompareTo(".csv") != 0 && Path.GetExtension(openFileDialog1.FileName).CompareTo(".arff") != 0)
                    throw new FileNotFoundException();
                if (Path.GetExtension(openFileDialog1.FileName).CompareTo(".csv") == 0)
                {
                    Columns.thuoctinh = ("No.," + sr.ReadLine()).Split(',');// tach cac thuoc tinh ra khoi chuoi
                    listView1.Items.Clear();
                    Table.mau.Clear(); // index was out of range
                    // hien thuoc tinh len listview
                    lb_filename.Text = Path.GetFileNameWithoutExtension(openFileDialog1.FileName);
                    lb_attributes.Text = (Columns.thuoctinh.Length - 1).ToString();
                    for (int i = 1; i < Columns.thuoctinh.Length; i++)
                    {
                        AddLine(listView1, i, Columns.thuoctinh[i]);
                    }
                    int ii = 1;
                    //doc du lieu tu file csv
                    while (!sr.EndOfStream)
                    {
                        Dong row = new Dong();
                        String line = ii.ToString() + "," + sr.ReadLine();
                        row.giatri = line.Split(','); //row.giatri[] : mang cac gia tri co kieu la string
                        Table.mau.Add(row);// them mot dong vao trong List<dong>
                        ii++;
                    }
                    sr.Close();
                    lb_instances.Text = Table.mau.Count.ToString();
                    ((Control)this.tabPage2).Enabled = true;
                }
                else if (Path.GetExtension(openFileDialog1.FileName).CompareTo(".arff") == 0)
                {
                    listView1.Items.Clear();
                    Table.mau.Clear(); // index was out of range
                    String chuthich = "";
                    do
                    {
                        chuthich = sr.ReadLine();
                    }
                    while (!sr.EndOfStream && chuthich.StartsWith("%"));
                    while (chuthich.Length == 0)
                    {
                        chuthich = sr.ReadLine();
                        //MessageBox.Show(chuthich);
                    }
                    #region xac dinh thuoc tinh
                    List<String> lstThuocTinh = new List<string>();
                    do
                    {
                        if (chuthich.StartsWith("@relation"))
                        {
                            lb_filename.Text = chuthich.Split(' ')[1];
                        }
                        if ((chuthich.StartsWith("@attribute")))
                        {
                            //MessageBox.Show(chuthich.Split(' ')[1]);
                            //AddLine(listView1, tt, chuthich.Split(' ')[1]);
                            //tt++;
                            lstThuocTinh.Add(chuthich.Split(' ')[1]);
                        }
                        chuthich = sr.ReadLine();
                        while (chuthich.Length == 0)
                        {
                            chuthich = sr.ReadLine();
                            //MessageBox.Show(chuthich);
                        }
                    } while (!sr.EndOfStream && chuthich.StartsWith("@"));

                    Columns.thuoctinh = lstThuocTinh.ToArray();
                    for (int i = 0; i < Columns.thuoctinh.Length; i++)
                    {
                        AddLine(listView1, i, Columns.thuoctinh[i]);
                    }

                    #endregion
                    #region xac dinh tung dong
                    while (chuthich.Length == 0)
                    {
                        chuthich = sr.ReadLine();
                    }
                    do
                    {

                        if ((chuthich.StartsWith("@data")))
                        {
                            //MessageBox.Show(chuthich);
                        }
                        else
                        {
                            // MessageBox.Show(chuthich);
                            Dong row = new Dong();
                            row.giatri = chuthich.Split(',');
                            Table.mau.Add(row);

                        }

                        chuthich = sr.ReadLine();


                    } while (!sr.EndOfStream);
                    #endregion
                    Dong row2 = new Dong();
                    row2.giatri = chuthich.Split(',');
                    Table.mau.Add(row2);
                    sr.Close();
                    lb_instances.Text = Table.mau.Count.ToString();
                    ((Control)this.tabPage2).Enabled = true;
                }
                else
                    MessageBox.Show("Dinh Dang khong Hop Le");
            }
            catch (FileNotFoundException)
            {
                MessageBox.Show("Định dạng tập tin không hợp lệ [.csv] hoặc [.arff]");
            }
        }
        // HIEN THON TIN CUA THUOC TINH DUOC CHON
        private void listView1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (listView1.SelectedItems.Count >= 1)
            {
                lb_attName.Text = listView1.SelectedItems[0].SubItems[1].Text; // lay ten thuoc tinh
                int iCot = int.Parse(listView1.SelectedItems[0].SubItems[0].Text); // lay chi so cot cua thuoc tinh
                // List<int> iMissing = new List<int>();
                int[] arr = Missing_getType(Table, iCot);
                lb_missing.Text = arr[0].ToString();
                if (arr[1] == 0)
                {
                    lb_type.Text = "Nominal";
                    listView2.Items.Clear();
                }
                else
                {
                    lb_type.Text = "Numeric";
                    Double[] stc = Statics(Table, iCot);
                    listView2.Items.Clear();
                    listView2.Items.Add("Minimum").SubItems.Add(stc[0].ToString());
                    listView2.Items.Add("Maximum").SubItems.Add(stc[1].ToString());
                    listView2.Items.Add("Mean").SubItems.Add(Math.Round(stc[2], 3).ToString());
                    listView2.Items.Add("StdDev").SubItems.Add(stdDev(Table, iCot).ToString());
                }

                /*
                lb_missing.Text = countMissing(Table, iCot).ToString(); //iCot: chi so cot trong csdl
                int type = getType(Table, iCot);
                if (type == 0)
                    lb_type.Text = "Nominal";
                else
                    lb_type.Text = "Numeric";
               // String mode = maxFrequency(Table, iCot);
               */
            }
        }
        //LUU FILE
        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                saveFileDialog1.ShowDialog();
                SaveFile(saveFileDialog1.FileName);
            }
            catch (ArgumentException ex)
            {
            }
        }
        // THAY THE DU LIEU BI THIEU
        private void button3_Click(object sender, EventArgs e)
        {
            replaceMissingvalue(Table, Columns);
        }
        //CHUAN HOA MIN-MAX
        private void button4_Click(object sender, EventArgs e)
        {
            try
            {
                int iAtb = int.Parse(listView1.SelectedItems[0].SubItems[0].Text);
                //List<bin> bins=binning(Table, iAtb, 7);
                min_max_Normalize(Table, iAtb, 0, 1);
            }
            catch (ArgumentOutOfRangeException)
            { MessageBox.Show("Column incorrect"); }
            catch (InvalidDataException)
            { MessageBox.Show("Is numerical ?"); }
        }
        // CHUAN HOA Z-SCORE
        private void button5_Click(object sender, EventArgs e)
        {


            try
            {
                int iAtb = int.Parse(listView1.SelectedItems[0].SubItems[0].Text);
                double stddev = stdDev(Table, iAtb);
                z_score_Normalize(Table, iAtb, stddev);
            }
            catch (ArgumentOutOfRangeException)
            { MessageBox.Show("Column incorrect"); }
            catch (InvalidDataException)
            { MessageBox.Show("Is numerical ?"); }
            //int iCot = 1;
            //double[] sts = Statics(Table,iCot);
            //double min=sts[0];
            //double max=sts[1];
            //List<bin> bins = new List<bin>();
            //int n=3;
            //int i=1;
            //int j=n;
            //while(i<=n)
            //{
            //    bin bin = new bin();
            //    bin.Min=min+((max-min)*(i-1))/n;
            //    MessageBox.Show(bin.Min.ToString());
            //}
        }
        //XEM TAP DU LIEU
        private void btn_viewset_Click(object sender, EventArgs e)
        {
            try
            {
                ViewSet frm2 = new ViewSet(Table, Columns);
                frm2.Show();
            }
            catch (Exception)
            { MessageBox.Show("Chưa chọn tập dữ liệu"); }
        }
        //CHIA GIO THEO CHIEU RONG
        private void btn_EW_Click(object sender, EventArgs e)
        {
            try
            {
                InputForm1 Inputfrm = new InputForm1();
                Inputfrm.ShowDialog();
                Bang tb = Table;
                int iCot = Inputfrm.Index;
                List<bin> bins = binning(tb, iCot, Inputfrm.Binnumber);
                //sapxepcot(tb, iCot);
                if (Inputfrm.Sapxep == true)
                    sapxepcot(tb, iCot);
                for (int i = 0; i < Table.mau.Count; i++)
                    if (tb.mau[i].giatri[iCot].CompareTo("?") != 0)
                    {
                        double a = double.Parse(tb.mau[i].giatri[iCot], System.Globalization.CultureInfo.CurrentCulture);
                        for (int j = 0; j < bins.Count; j++)
                        {
                            if (a < bins[j].Max)
                            {
                                if (j == 0)
                                {
                                    tb.mau[i].giatri[iCot] = "[ -inf; " + bins[j].Max.ToString() + " )";
                                    break;
                                }
                                else
                                {
                                    tb.mau[i].giatri[iCot] = "[ " + bins[j].Min.ToString() + " ; " + bins[j].Max.ToString() + " )";
                                    break;
                                }
                            }
                            else if (a >= bins[bins.Count - 1].Min)
                            {
                                tb.mau[i].giatri[iCot] = "[ " + bins[bins.Count - 1].Min.ToString() + " ; +inf)";
                                break;
                            }

                        }
                    }
            }
            catch (NullReferenceException ex)
            {
                MessageBox.Show("Thông tin không chính xác");
            }
            catch (IndexOutOfRangeException)
            {
                MessageBox.Show("Chỉ số cột không chính xác");
            }
            catch (FormatException)
            {
                MessageBox.Show("Cột phải có dữ liệu là numeric");
            }
        }
        // CHIA GIO THEO CHIEU SAU
        private void btn_DW_Click(object sender, EventArgs e)
        {
            try
            {
                InputForm1 Inputfrm = new InputForm1();
                Inputfrm.ShowDialog();
                Bang tb = Table;
                int iCot = Inputfrm.Index;
                int n = Inputfrm.Binnumber;
                sapxepcot(tb, iCot);
                List<bin> bins = binning2(tb, iCot, n);
                int m = 0;
                for (int j = 0; j < bins.Count; j++)
                {
                    double tmp = 0;
                    int i = 0;
                    // DUYET TUNG PHAN TU DE THEM VAO BIN TUONG UNG
                    if (i + m < tb.mau.Count - 1)
                    {
                        for (i = 0; (i < n || (double)i <= (double)tb.mau.Count / n) && i + m < tb.mau.Count; i++)
                        {
                            double x = double.Parse(tb.mau[i + m].giatri[iCot], System.Globalization.CultureInfo.CurrentCulture);
                            bins[j].Element.Add(x);
                            tmp = x;
                        }
                        m = (m + i);
                        // them phan tu neu trung voi gio truoc
                        if (m < tb.mau.Count)
                        {
                            double b = double.Parse(tb.mau[m].giatri[iCot], System.Globalization.CultureInfo.CurrentCulture);
                            while (b == tmp)
                            {
                                bins[j].Element.Add(b);
                                m++;
                                b = double.Parse(tb.mau[m].giatri[iCot], System.Globalization.CultureInfo.CurrentCulture);
                            }
                        }
                        bins[j].Min = bins[j].Element[0];
                        bins[j].Max = bins[j].Element[bins[j].Element.Count - 1];
                    }
                }
                // duyet lai csdl thay the gia tri bang cac khoang tuong ung
                for (int i = 0; i < Table.mau.Count; i++)
                    if (Table.mau[i].giatri[iCot].CompareTo("?") != 0)
                    {
                        double a = double.Parse(Table.mau[i].giatri[iCot], System.Globalization.CultureInfo.CurrentCulture);
                        for (int j = 0; j < bins.Count; j++)
                        {
                            if (a <= bins[j].Max)
                            {
                                Table.mau[i].giatri[iCot] = "( " + bins[j].Min.ToString() + " ; " + bins[j].Max.ToString() + " ]";
                                break;
                            }
                            if (j == bins.Count - 1)
                            {
                                Table.mau[i].giatri[iCot] = "( " + bins[j].Min.ToString() + " ; +inf]";
                                break;
                            }
                        }
                    }
                if (Inputfrm.Sapxep == false)
                    sapxepcot(tb, 0);
            }
            catch (NullReferenceException ex)
            {
                MessageBox.Show("Information incorrect");
            }
            catch (IndexOutOfRangeException)
            {
                MessageBox.Show("Column index invalid");
            }
            catch (FormatException)
            {
                MessageBox.Show("numeric is accepted");
            }

        }
        private void tab2_btnview_Click(object sender, EventArgs e)
        {
            try
            {
                ViewSet frm2 = new ViewSet(Table, Columns);
                frm2.Show();
            }
            catch (Exception)
            { MessageBox.Show("Chưa chọn tập dữ liệu"); }
        }
        #endregion
        #region MO TA VE THONG TIN CUA 1 BIN
        // MO TA VE THONG TIN CUA 1 BIN
        class bin
        {
            double min; // GIA TRI NHO NHAT CUA BIN

            public double Min
            {
                get { return min; }
                set { min = value; }
            }
            double max; // GIA TRI LON NHAT CUA BIN

            public double Max
            {
                get { return max; }
                set { max = value; }
            }
            List<double> element; // SO PHAN TU CUA BIN

            public List<double> Element
            {
                get { return element; }
                set { element = value; }
            }
            public bin()
            {
                min = 0;
                max = 0;
                element = new List<double>();
            }

        }
        #endregion
       
        private void initialize()
        {
            rtb_thongbao.Text = "Các trung tâm khởi tạo:\n";

            Centroid d = centroidOfData(SAMPLES);
            List<double> distlst = distPointToCentroid(SAMPLES, d);

            for (int i = 0; i < NUM_CLUSTERS; i++)
            {
                Centroid c = findPoint(SAMPLES, d, distlst[i]);
                centroids.Add(c);
            }

            //List<double> lst = toDoubleArray(Table.mau[0].giatri);
            //Centroid c = new Centroid(lst);
            //centroids.Add(c);

            //lst = toDoubleArray(Table.mau[1].giatri);///////////////////////////////
            //c = new Centroid(lst);
            //centroids.Add(c);

            for (int i = 0; i < NUM_CLUSTERS; i++)
            {
                String Out = "( ";
                for (int j = 0; j < centroids[i].getDimension(); j++)
                {
                    Out = Out + centroids[i].getElementAt(j).ToString();
                    if (j < centroids[i].getDimension() - 1)
                        Out += ",";
                }
                rtb_thongbao.Text += Out + " )\n";
            }
            return;
        }
        private static void kMeanCluster()
        {
            double bigNumber = Math.Pow(10, 10);
            double minimum = bigNumber;
            double distance = 0.0;
            int sampleNumber = 0;
            int cluster = 0;
            bool isStillMoving = true;
            Data newData = null;
            while (dataset.Count < TOTAL_DATA)
            {
                List<double> lstnewData = new List<double>();
                for (int sp = 0; sp < SAMPLES[sampleNumber].getDimension(); sp++)
                {
                    lstnewData.Add(SAMPLES[sampleNumber].getElementAt(sp));
                }
                newData = new Data(lstnewData);
                dataset.Add(newData);
                minimum = bigNumber;

                for (int i = 0; i < NUM_CLUSTERS; i++)
                {
                    distance = dist(newData, centroids[i]);
                    if (distance < minimum)
                    {
                        minimum = distance;
                        cluster = i;
                    }
                }
                newData.cluster(cluster);
                for (int i = 0; i < NUM_CLUSTERS; i++) // duyet toan bo cac cluster
                {
                    double[] totalOfDimensons = new double[newData.getDimension()];
                    int totalInCluster = 0;
                    for (int j = 0; j < dataset.Count; j++)
                    {
                        if (dataset[j].cluster() == i)
                        {
                            for (int sp2 = 0; sp2 < centroids[i].getDimension(); sp2++)
                            {
                                totalOfDimensons[sp2] += dataset[j].getElementAt(sp2);
                            }
                            totalInCluster++;
                        }

                    }
                    if (totalInCluster > 0)
                    {
                        for (int sp2 = 0; sp2 < centroids[i].getDimension(); sp2++)
                        {
                            centroids[i].setElementAt(sp2, totalOfDimensons[sp2] / totalInCluster);
                        }
                    }

                }
                sampleNumber++;
            }
            while (isStillMoving)
            {
                for (int i = 0; i < NUM_CLUSTERS; i++)
                {
                    double[] totalOfDimensons = new double[newData.getDimension()];
                    int totalInCluster = 0;
                    for (int j = 0; j < dataset.Count; j++)
                    {
                        if (dataset[j].cluster() == i)
                        {
                            for (int sp2 = 0; sp2 < centroids[i].getDimension(); sp2++)
                            {
                                totalOfDimensons[sp2] += dataset[j].getElementAt(sp2);
                            }
                            totalInCluster++;
                        }

                    }
                    if (totalInCluster > 0)
                    {
                        for (int sp2 = 0; sp2 < centroids[i].getDimension(); sp2++)
                        {
                            centroids[i].setElementAt(sp2, totalOfDimensons[sp2] / totalInCluster);
                        }
                    }
                }
                isStillMoving = false;
                for (int i = 0; i < dataset.Count; i++)
                {
                    Data tempData = dataset[i];
                    minimum = bigNumber;
                    for (int j = 0; j < NUM_CLUSTERS; j++)
                    {
                        distance = dist(tempData, centroids[j]);
                        if (distance < minimum)
                        {
                            minimum = distance;
                            cluster = j;
                        }
                    }
                    tempData.cluster(cluster);
                    if (tempData.cluster() != cluster)
                    {
                        tempData.cluster(cluster);
                        isStillMoving = true;
                    }
                }
            }
            return;

        }
        private void createListData()
        {
            
            for (int i = 0; i < Table.mau.Count; i++)
            {
                List<double> lst = toDoubleArray(Table.mau[i].giatri);
                Data d = new Data(lst);
                SAMPLES.Add(d);
            }
            TOTAL_DATA = SAMPLES.Count;

        }

        private static double dist(Data d, Centroid c)
        {
            double sum = 0.0;
            for (int i = 0; i < d.getDimension(); i++)
            {
                double x = d.getElementAt(i) - c.getElementAt(i);
                sum += (x * x);
            }
            return Math.Sqrt(sum);
        }
        private void tab3_btnRun_Click(object sender, EventArgs e)
        {
            Stopwatch sw = new Stopwatch();
            try
            {
               
                #region In Kết Quả
                bool kq = int.TryParse(tab2_txtNUM_CLUSTERS.Text, out NUM_CLUSTERS);
                if (kq == false)
                {
                    MessageBox.Show("Chưa nhập K");
                    return;
                }
                rtb_thongbao.Clear();
                SAMPLES.Clear();
                dataset.Clear();
                centroids.Clear();
                createListData();
                initialize();
                sw.Start();
                kMeanCluster();
                sw.Stop();
                for (int i = 0; i < NUM_CLUSTERS; i++)
                {
                    long count = 0;
                    rtb_thongbao.Text += "Cluster " + (i+1).ToString() + " gồm có: ";
                    for (int j = 0; j < TOTAL_DATA; j++)
                    {
                        if (dataset[j].cluster() == i)
                        {
                            count++;
                        }
                        
                    }
                    double tb = ((double)count / SAMPLES.Count)*100;
                    rtb_thongbao.Text += count.ToString() +" ( "+Math.Round(tb,2).ToString()+" % )"+"\n";
                    rtb_thongbao.Text += "\n";
                }

                rtb_thongbao.Text += "Các trung tâm cuối cùng:\n";
                for (int i = 0; i < NUM_CLUSTERS; i++)
                {
                    String Out = "( ";
                    for (int j = 0; j < centroids[i].getDimension(); j++)
                    {
                        Out = Out + Math.Round(centroids[i].getElementAt(j), 2).ToString();
                        if (j < centroids[i].getDimension() - 1)
                            Out += ",";
                    }
                    rtb_thongbao.Text += Out + " )\n";
                }
                rtb_thongbao.Text += "\nKết thúc";
                #endregion
                
                rtb_thongbao.Text +=" "+ Math.Round(sw.Elapsed.TotalSeconds,2).ToString()+" s";
            }
            catch (ArgumentOutOfRangeException ex)
            {
                MessageBox.Show("Số cụm phải nhỏ hơn số mẫu");
            }
        }
            

    }
}
